home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 32 / IOPROG_32.ISO / SOFT / SqlEval7 / MSOLAP / samples / Samples.exe / VbDSOExample / Sales cube from scratch.bas < prev    next >
Encoding:
BASIC Source File  |  1998-10-30  |  54.7 KB  |  1,434 lines

  1. Attribute VB_Name = "DSOSampleCode"
  2. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  3. '
  4. '   Sales cube from scratch.bas - contains the basic functions for creating a
  5. '   cube.
  6. '
  7. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  8. Option Explicit
  9. Option Compare Text
  10.  
  11.  
  12. ' module level variables
  13. Public m_dsoServer   As DSO.Server
  14. Public m_dsoDatabase As DSO.MDStore
  15. Public m_dsoCube     As DSO.MDStore
  16.  
  17.  
  18. '
  19. '   Initialize - initialize the sample application
  20. '
  21. '
  22. Public Sub Initialize()
  23.     ' If the DSO server object has already been in use
  24.     '   then call CloseServer method
  25.     ' NOTE: CloseServer method releases all of the resources
  26.     '       acquired by DSO.  It is important to call this
  27.     '       method when the DSO server object is not needed
  28.     '       any longer
  29.     If Not m_dsoServer Is Nothing Then
  30.         m_dsoServer.CloseServer
  31.     End If
  32. End Sub
  33.  
  34. '
  35. '   ConnectToServer - create and connect to the DSO server
  36. '
  37. Public Sub ConnectToServer()
  38.     ' create an instance of the server object
  39.     Dim dsoServer As DSO.Server
  40.     Set dsoServer = New DSO.Server
  41.     
  42.     ' connect to the server
  43.     On Error GoTo Err_Connect
  44.     dsoServer.Connect frmMain.txtServerName
  45.                                         
  46.     ' store the reference to the server object
  47.     ' so that other methods can use it
  48.     Set m_dsoServer = dsoServer
  49.     
  50. Exit Sub
  51.  
  52. Err_Connect:
  53.     ' Failed to connect to the server.
  54.     ' Possible reasons:
  55.     '   - the Microsoft SQL Server OLAP Server is not running
  56.     '   - the machine on which the OLAP Server is running cannot be reached
  57.     '   - the machine on which DSO application is running is not connected
  58.     '       to the network
  59.     '   - you are not a member of the OLAP Administrators user group on the
  60.     '       server machine
  61.     
  62.     MsgBox "Failed to connect to the server" & vbCrLf & Err.Description
  63. End Sub
  64.  
  65.  
  66. '
  67. '   CreateDatabase - create new database
  68. '
  69. Public Sub CreateDatabase()
  70.     ' call the database "DSOSample"
  71.     Dim sDatabaseName As String
  72.     sDatabaseName = "DSOSample"
  73.     
  74.     ' check if a database with the same name
  75.     ' already exists on the server
  76.     If m_dsoServer.MDStores.Find(sDatabaseName) Then
  77.         
  78.         ' delete the existing database
  79.         On Error GoTo Err_DeleteDatabase
  80.         m_dsoServer.MDStores.Remove sDatabaseName
  81.     End If
  82.     
  83.     ' create the new database
  84.     On Error GoTo Err_CreateDatabase
  85.     Dim dsoDatabase As DSO.MDStore
  86.     Set dsoDatabase = m_dsoServer.MDStores.AddNew(sDatabaseName)
  87.     
  88.     ' set the database description
  89.     dsoDatabase.Description = "SampleDSO database contains Warehouse cube."
  90.     
  91.     ' create a few custom properties
  92.     dsoDatabase.CustomProperties.Add "Marin Bezic", "Creator", vbString
  93.     dsoDatabase.CustomProperties.Add Date, "Date created", vbDate
  94.     
  95.     ' save the database definition in the OLAP server's metadata repository
  96.     On Error GoTo Err_Update
  97.     dsoDatabase.Update
  98.     
  99.     ' store the reference to the database object
  100.     ' so that other methods can use it
  101.     Set m_dsoDatabase = dsoDatabase
  102.     
  103. Exit Sub
  104.  
  105. Err_DeleteDatabase:
  106.     ' Failed to remove the database from the server.
  107.     ' Possible reasons:
  108.     '   - the OLAP server is not running or unreachable
  109.     '   - the database is being used by another DSO application
  110.     
  111. Err_CreateDatabase:
  112.     ' Failed to create the database on the server.
  113.     ' Possible reasons:
  114.     '   - the OLAP server is not running or unreachable
  115.     '   - the DSO server object is being locked by another DSO application
  116.     '       the server object is locked while AddNew method is executing on
  117.     '       the server's MDStores collection
  118.     '   - the metadata repository is unreachable
  119.     
  120. Err_Update:
  121.     ' Failed to persist the database definition in the metadata repository
  122.     ' Possible reasons:
  123.     '   - the metadata repository is unreachable
  124.     '       you can see where the metadata repository resides by looking
  125.     '       up the following registry entry:
  126.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  127.     '           Repository Connection String
  128.     '   - the DSO database object is being locked by another DSO application
  129.     '       it is not possible for two DSO apps to persist the same object
  130.     '       at the same time
  131.     '       it is not possible to persist a DSO object, it another DSO app
  132.     '       has explicitly locked it
  133.     
  134.     MsgBox "Create database failed" & vbCrLf & Err.Description
  135. End Sub
  136.  
  137.  
  138. '
  139. '   CreateDatasource - create the new datasource
  140. '
  141. Public Sub CreateDatasource()
  142.     ' create the new datasource that points to the
  143.     ' sample FoodMart database
  144.     On Error GoTo Err_CreateDatasource
  145.     Dim dsoDatasource As DSO.DataSource
  146.     Set dsoDatasource = m_dsoDatabase.DataSources.AddNew("Foodmart Sample Database")
  147.     
  148.     ' set the OleDB connection string
  149.     '   the connection string is used to establish the connection
  150.     '   to the relational database that contains the dimension and
  151.     '   fact tables
  152.     ' we will use OleDB provider for Jet
  153.     dsoDatasource.ConnectionString = _
  154.             "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Program Files\OLAP Services\Samples\FoodMart.mdb;JET OLEDB:SFP=True;"
  155.     
  156.     ' save the datasource definition in the metadata repository
  157.     On Error GoTo Err_Update
  158.     dsoDatasource.Update
  159.     
  160. Exit Sub
  161.  
  162. Err_CreateDatasource:
  163.     ' Failed to create the datasource.
  164.     ' Possible reasons:
  165.     '   - the DSO database object is being locked by another DSO application
  166.     '       a DSO object is locked while AddNew method is executing on
  167.     '       one of its collections (Datasources, MDStores, ...)
  168.     '   - the metadata repository is unreachable
  169.     
  170. Err_Update:
  171.     ' Failed to persist the datasource definition in the metadata repository
  172.     ' Possible reasons:
  173.     '   - the metadata repository is unreachable
  174.     '       you can see where the metadata repository resides by looking
  175.     '       up the following registry entry:
  176.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  177.     '           Repository Connection String
  178.     '   - the DSO datasource object is being locked by another DSO application
  179.     '       it is not possible for two DSO apps to persist the same object
  180.     '       at the same time
  181.     '       it is not possible to persist a DSO object, it another DSO app
  182.     '       has explicitly locked it
  183.     
  184.     MsgBox "Create datasource failed" & vbCrLf & Err.Description
  185. End Sub
  186.  
  187. '
  188. '   CreateDimensionStore - create the Store dimension
  189. '
  190. '   NOTE: the Store dimension is an example of a dimension
  191. '         that is based on one dimension table (star schema)
  192. '
  193. Public Sub CreateDimensionStore()
  194.     ' create the Store dimension in the database's
  195.     ' Dimensions collection
  196.     On Error GoTo Err_Create
  197.     Dim dsoDimension As DSO.Dimension
  198.     Set dsoDimension = m_dsoDatabase.Dimensions.AddNew("Store")
  199.  
  200.     ' set the dimension description
  201.     dsoDimension.Description = "The stores hierarchy"
  202.     
  203.     ' set the dimension's datasource
  204.     Set dsoDimension.DataSource = m_dsoDatabase.DataSources("Foodmart Sample Database")
  205.     
  206.     ' get the quoting characters from the datasource
  207.     Dim sLQuote As String, sRQuote As String
  208.     sLQuote = dsoDimension.DataSource.OpenQuoteChar
  209.     sRQuote = dsoDimension.DataSource.CloseQuoteChar
  210.     
  211.     ' set the dimension type
  212.     dsoDimension.DimensionType = dimRegular
  213.     
  214.     ' set the comma separated list of the dimension tables
  215.     ' NOTE: the tables must be quoted
  216.     ' the Store dimension uses only the "store" table
  217.     dsoDimension.FromClause = sLQuote & "store" & sRQuote
  218.                               
  219.     ' define the joins between tables used by this dimension
  220.     ' the format of this property is
  221.     '   (table1.columnX = table2.columnY) and (table2.columnZ = table3.columnW)
  222.     ' since the Store dimension is based on only one table, we have no joins
  223.     dsoDimension.JoinClause = ""
  224.     
  225.     
  226.     '
  227.     ' create dimension levels
  228.     '
  229.     Dim dsoLevel As DSO.Level
  230.     
  231.     '
  232.     ' create the All level
  233.     '   the All level is the top-most level in the dimension hierarcy
  234.     On Error GoTo Err_Create
  235.     Set dsoLevel = dsoDimension.Levels.AddNew("All")
  236.     
  237.     ' set the level type
  238.     dsoLevel.LevelType = levAll
  239.     
  240.     ' the All level has only one member
  241.     ' set the MemberKeyColumn of the All level to a constant
  242.     ' this constant is at the same time the name of that single member
  243.     dsoLevel.MemberKeyColumn = "All Stores"
  244.     
  245.     '
  246.     ' create the Store Country level
  247.     '   the Store Country level contains all of the countries
  248.     On Error GoTo Err_Create
  249.     Set dsoLevel = dsoDimension.Levels.AddNew("Store Country")
  250.     
  251.     ' set the level type
  252.     dsoLevel.LevelType = levRegular
  253.     
  254.     ' define which column contains the level member keys
  255.     ' sLQuote and sRQuote are obtained from dsoDimension.Datasource
  256.     ' NOTE: the tables and columns must be quoted using the quoting
  257.     '       characters obtained from the dimension's datasource
  258.     dsoLevel.MemberKeyColumn = sLQuote & "store" & sRQuote & "." & _
  259.                                sLQuote & "store_country" & sRQuote
  260.  
  261.     ' tell DSO how many members this level has
  262.     ' this information will be used during the design of aggregations
  263.     '   when determining the optimal set of aggregations
  264.     ' there are 3 countries in the "store" table: Mexico, Canada, and USA
  265.     dsoLevel.EstimatedSize = 3
  266.     
  267.     ' this level contains unique members
  268.     dsoLevel.IsUnique = True
  269.     
  270.     ' DSO needs to know what is the type and maximum size of the members keys
  271.     ' NOTE: the ColumnSize property needs to be set only for
  272.     '       levels that have string members
  273.     dsoLevel.ColumnType = adChar
  274.     dsoLevel.ColumnSize = 6         ' the longest members ("Mexico", "Canada")
  275.                                     ' can fit in 6 characters
  276.     
  277.     ' specify how should the level members be ordered
  278.     ' we want the countries ordered by Name
  279.     dsoLevel.Ordering = orderName
  280.     
  281.     '
  282.     ' create the Store State level
  283.     '   the Store State level contains all of the states
  284.     On Error GoTo Err_Create
  285.     Set dsoLevel = dsoDimension.Levels.AddNew("Store State")
  286.     
  287.     ' set the level type
  288.     dsoLevel.LevelType = levRegular
  289.     
  290.     ' "store_state" column contains members for this level
  291.     dsoLevel.MemberKeyColumn = sLQuote & "store" & sRQuote & "." & _
  292.                                sLQuote & "store_state" & sRQuote
  293.  
  294.     ' there are 10 distinct states in the "store" table
  295.     dsoLevel.EstimatedSize = 10
  296.     
  297.     ' this level contains unique members,
  298.     ' i.e. no state appears in more than one country
  299.     dsoLevel.IsUnique = True
  300.     
  301.     ' DSO needs to know what is the type and maximum size of the members keys
  302.     dsoLevel.ColumnType = adChar
  303.     dsoLevel.ColumnSize = 9             ' the longest member ("Zacatecas")
  304.                                         ' can fit in 9 characters
  305.     
  306.     ' we want the states ordered by Name
  307.     dsoLevel.Ordering = orderName
  308.     
  309.     '
  310.     ' create the Store City level
  311.     '   the Store City level contains all of the cities
  312.     On Error GoTo Err_Create
  313.     Set dsoLevel = dsoDimension.Levels.AddNew("Store City")
  314.     
  315.     ' set the level type
  316.     dsoLevel.LevelType = levRegular
  317.     
  318.     ' "store_city" column contains members for this level
  319.     dsoLevel.MemberKeyColumn = sLQuote & "store" & sRQuote & "." & _
  320.                                sLQuote & "store_city" & sRQuote
  321.  
  322.     ' there are 23 distinct cities in the "store" table
  323.     dsoLevel.EstimatedSize = 23
  324.     
  325.     ' this level contains unique members,
  326.     ' i.e. no city appears in more than one state
  327.     ' NOTE: this is often not the case,
  328.     '       for example: Portland (Oregon) and Portland (Maine)
  329.     dsoLevel.IsUnique = True
  330.     
  331.     ' DSO needs to know what is the type and maximum size of the members keys
  332.     dsoLevel.ColumnType = adChar
  333.     dsoLevel.ColumnSize = 13            ' the longest member ("San Francisco")
  334.                                         ' can fit in 13 characters
  335.     
  336.     ' we want the cities ordered by Name
  337.     dsoLevel.Ordering = orderName
  338.     
  339.     
  340.     '
  341.     ' create the Store Name level
  342.     '   the Store Name level contains all of the individual stores
  343.     On Error GoTo Err_Create
  344.     Set dsoLevel = dsoDimension.Levels.AddNew("Store Name")
  345.     
  346.     ' set the level type
  347.     dsoLevel.LevelType = levRegular
  348.     
  349.     ' "store_id" column contains members for this level
  350.     dsoLevel.MemberKeyColumn = sLQuote & "store" & sRQuote & "." & _
  351.                                sLQuote & "store_id" & sRQuote
  352.  
  353.     ' we will use column "store_name" for member names
  354.     dsoLevel.MemberNameColumn = sLQuote & "store" & sRQuote & "." & _
  355.                                 sLQuote & "store_name" & sRQuote
  356.     
  357.     ' there are 24 distinct stores in the "store" table
  358.     dsoLevel.EstimatedSize = 24
  359.     
  360.     ' this level contains unique members,
  361.     ' i.e. no store appears in more than one city
  362.     dsoLevel.IsUnique = True
  363.     
  364.     ' DSO needs to know what is the data type of the level members keys
  365.     ' since this level has numeric member keys, we do not need to set the ColumnSize
  366.     dsoLevel.ColumnType = adInteger
  367.     
  368.     ' we want the stores ordered by Name
  369.     dsoLevel.Ordering = orderName
  370.     
  371.     '
  372.     ' create the member properties for the Store Name level
  373.     '
  374.     Dim dsoMemberProperty As DSO.MemberProperty
  375.     
  376.     ' create a member property containing the name of the store manager
  377.     Set dsoMemberProperty = dsoLevel.MemberProperties.AddNew("Store Manager")
  378.     ' set the column which contains the names of the managers
  379.     dsoMemberProperty.SourceColumn = sLQuote & "store" & sRQuote & "." & _
  380.                                      sLQuote & "store_manager" & sRQuote
  381.     
  382.     ' create a member property containing the type of the store
  383.     Set dsoMemberProperty = dsoLevel.MemberProperties.AddNew("Store Type")
  384.     ' set the column which contains the store type
  385.     dsoMemberProperty.SourceColumn = sLQuote & "store" & sRQuote & "." & _
  386.                                      sLQuote & "store_type" & sRQuote
  387.     
  388.     ' save the dimension definition in the metadata repository
  389.     On Error GoTo Err_Update
  390.     dsoDimension.Update
  391.     
  392. Exit Sub
  393.  
  394. Err_Create:
  395.     ' Failed to create the object.
  396.     ' Possible reasons:
  397.     '   - the DSO database object is being locked by another DSO application
  398.     '       a DSO object is locked while AddNew method is executing on
  399.     '       one of its collections (Datasources, MDStores, Dimensions...)
  400.     '   - the metadata repository is unreachable
  401.  
  402. Err_Update:
  403.     ' Failed to persist the dimension definition in the metadata repository
  404.     ' Possible reasons:
  405.     '   - the metadata repository is unreachable
  406.     '       you can see where the metadata repository resides by looking
  407.     '       up the following registry entry:
  408.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  409.     '           Repository Connection String
  410.     '   - the DSO dimension object is being locked by another DSO application
  411.     '       it is not possible for two DSO apps to persist the same object
  412.     '       at the same time
  413.     '       it is not possible to persist a DSO object, it another DSO app
  414.     '       has explicitly locked it
  415.  
  416.     MsgBox "Create dimension Store failed" & vbCrLf & Err.Description
  417. End Sub
  418.  
  419. '
  420. '   CreateDimensionTime - create the Time dimension
  421. '
  422. '   NOTE: the Time dimension is an example of a time dimension
  423. '         that is based on multiple time columns (year, quarter, month)
  424. '
  425. Public Sub CreateDimensionTime()
  426.     ' create the Time dimension in the database's
  427.     ' Dimensions collection
  428.     On Error GoTo Err_Create
  429.     Dim dsoDimension As DSO.Dimension
  430.     Set dsoDimension = m_dsoDatabase.Dimensions.AddNew("Time")
  431.  
  432.     ' set the dimension description
  433.     dsoDimension.Description = "The time hierarchy"
  434.     
  435.     ' set the dimension's datasource
  436.     Set dsoDimension.DataSource = m_dsoDatabase.DataSources("Foodmart Sample Database")
  437.     
  438.     ' get the quoting characters from the datasource
  439.     Dim sLQuote As String, sRQuote As String
  440.     sLQuote = dsoDimension.DataSource.OpenQuoteChar
  441.     sRQuote = dsoDimension.DataSource.CloseQuoteChar
  442.     
  443.     ' set the dimension type to time dimension
  444.     ' NOTE: this is important as it enables the OLAP server to
  445.     '       apply time functions to members of this dimension
  446.     dsoDimension.DimensionType = dimTime
  447.     
  448.     ' set the comma separated list of the dimension tables
  449.     ' NOTE: the tables must be quoted
  450.     ' the Time dimension uses only the "time_by_day" table
  451.     dsoDimension.FromClause = sLQuote & "time_by_day" & sRQuote
  452.                               
  453.     ' define the joins between tables used by this dimension
  454.     ' the format of this property is
  455.     '   (table1.columnX = table2.columnY) and (table2.columnZ = table3.columnW)
  456.     ' since the Time dimension is based on only one table, we have no joins
  457.     dsoDimension.JoinClause = ""
  458.     
  459.     
  460.     '
  461.     ' create dimension levels
  462.     '
  463.     Dim dsoLevel As DSO.Level
  464.     
  465.     '
  466.     ' create the All level
  467.     '   the All level is the top-most level in the dimension hierarcy
  468.     On Error GoTo Err_Create
  469.     Set dsoLevel = dsoDimension.Levels.AddNew("All")
  470.     
  471.     ' set the level type
  472.     dsoLevel.LevelType = levAll
  473.     
  474.     ' the All level has only one member
  475.     ' set the MemberKeyColumn of the All level to a constant
  476.     ' this constant is at the same time the name of that single member
  477.     dsoLevel.MemberKeyColumn = "All Years"
  478.     
  479.     '
  480.     ' create the Year level
  481.     '   the Year level contains all of the years
  482.     On Error GoTo Err_Create
  483.     Set dsoLevel = dsoDimension.Levels.AddNew("Year")
  484.     
  485.     ' set the level type
  486.     dsoLevel.LevelType = levTimeYears
  487.     
  488.     ' define which column contains the level member keys
  489.     ' sLQuote and sRQuote are obtained from dsoDimension.Datasource
  490.     ' NOTE: the tables and columns must be quoted using the quoting
  491.     '       characters obtained from the dimension's datasource
  492.     ' NOTE: the alternative member for the year level can be
  493.     '           DatePart('yyyy',"time_by_day"."the_date")
  494.     dsoLevel.MemberKeyColumn = sLQuote & "time_by_day" & sRQuote & "." & _
  495.                                sLQuote & "the_year" & sRQuote
  496.  
  497.     ' tell DSO how many members this level has
  498.     ' this information will be used during the design of aggregations
  499.     '   when determining the optimal set of aggregations
  500.     ' there are 2 years in the "time_by_day" table: 1997 and 1998
  501.     dsoLevel.EstimatedSize = 2
  502.     
  503.     ' this level contains unique members
  504.     dsoLevel.IsUnique = True
  505.     
  506.     ' DSO needs to know what is the data and maximum size of the members keys
  507.     ' NOTE: the ColumnSize property needs to be set only for
  508.     '       levels that have string members
  509.     dsoLevel.ColumnType = adSmallInt
  510.     
  511.     ' specify how should the level members be ordered
  512.     ' we want the countries ordered by Name
  513.     dsoLevel.Ordering = orderName
  514.     
  515.     '
  516.     ' create the Quarter level
  517.     '   the Quarter level contains all of the quarters
  518.     On Error GoTo Err_Create
  519.     Set dsoLevel = dsoDimension.Levels.AddNew("Quarter")
  520.     
  521.     ' set the level type
  522.     dsoLevel.LevelType = levTimeQuarters
  523.     
  524.     ' "quarter" column contains members for this level
  525.     dsoLevel.MemberKeyColumn = sLQuote & "time_by_day" & sRQuote & "." & _
  526.                                sLQuote & "quarter" & sRQuote
  527.  
  528.     ' there are 8 distinct quarters in the "time_by_day" table
  529.     ' 4 belong to 1997, and 4 belong to 1998
  530.     dsoLevel.EstimatedSize = 8
  531.     
  532.     ' this level DOES NOT contains unique members
  533.     ' ex. Quarter 1 appears both in year 1997 and 1998
  534.     dsoLevel.IsUnique = False
  535.     
  536.     ' DSO needs to know what is the type and maximum size of the members keys
  537.     dsoLevel.ColumnType = adChar
  538.     dsoLevel.ColumnSize = 2             ' quarters are represented as Q1, Q2, ...
  539.                                         ' they can fit in 2 characters
  540.     
  541.     ' we want the quarters ordered by Name
  542.     dsoLevel.Ordering = orderName
  543.     
  544.     '
  545.     ' create the Month level
  546.     '   the Month level contains all of the months
  547.     On Error GoTo Err_Create
  548.     Set dsoLevel = dsoDimension.Levels.AddNew("Month")
  549.     
  550.     ' set the level type
  551.     dsoLevel.LevelType = levTimeMonths
  552.     
  553.     ' "month_of_year" column contains members for this level
  554.     dsoLevel.MemberKeyColumn = sLQuote & "time_by_day" & sRQuote & "." & _
  555.                                sLQuote & "month_of_year" & sRQuote
  556.  
  557.     ' we can use "the_month" column for names of the members (January, February, ...)
  558.     dsoLevel.MemberNameColumn = sLQuote & "time_by_day" & sRQuote & "." & _
  559.                                 sLQuote & "the_month" & sRQuote
  560.     
  561.     ' there are 24 distinct months in the "time_by_day" table
  562.     ' 12 belong to 1997, and 12 belong to 1998
  563.     dsoLevel.EstimatedSize = 24
  564.     
  565.     ' this level DOES NOT contain unique members,
  566.     ' ex. January appears both in 1997 and 1998
  567.     dsoLevel.IsUnique = False
  568.     
  569.     ' DSO needs to know what is the type and maximum size of the members keys
  570.     dsoLevel.ColumnType = adSmallInt
  571.     
  572.     ' we want the months ordered by Key (1, 2, 3, ...)
  573.     ' rather than by name (April, August, ...)
  574.     dsoLevel.Ordering = orderKey
  575.     
  576.     
  577.     ' save the dimension definition in the metadata repository
  578.     On Error GoTo Err_Update
  579.     dsoDimension.Update
  580.     
  581. Exit Sub
  582.  
  583. Err_Create:
  584.     ' Failed to create the object.
  585.     ' Possible reasons:
  586.     '   - the DSO database object is being locked by another DSO application
  587.     '       a DSO object is locked while AddNew method is executing on
  588.     '       one of its collections (Datasources, MDStores, Dimensions...)
  589.     '   - the metadata repository is unreachable
  590.  
  591. Err_Update:
  592.     ' Failed to persist the dimension definition in the metadata repository
  593.     ' Possible reasons:
  594.     '   - the metadata repository is unreachable
  595.     '       you can see where the metadata repository resides by looking
  596.     '       up the following registry entry:
  597.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  598.     '           Repository Connection String
  599.     '   - the DSO dimension object is being locked by another DSO application
  600.     '       it is not possible for two DSO apps to persist the same object
  601.     '       at the same time
  602.     '       it is not possible to persist a DSO object, it another DSO app
  603.     '       has explicitly locked it
  604.  
  605.     MsgBox "Create dimension Time failed" & vbCrLf & Err.Description
  606. End Sub
  607.  
  608. '
  609. '   CreateDimensionTimeFromDateTimeColumnFromDateTimeColumn - create the Time dimension
  610. '                                           based on the DateTime column
  611. '
  612. '   NOTE: this dimension is an example of how to create a time dimension
  613. '         by parsing the TimeDate column
  614. '         This rutine will work only with Access (Jet) databases since
  615. '         it utilizes Jet specific Date/Time functions
  616. Public Sub CreateDimensionTimeFromDateTimeColumn()
  617.     ' create the Time dimension in the database's
  618.     ' Dimensions collection
  619.     
  620.     On Error GoTo Err_Create
  621.     Dim dsoDimension As DSO.Dimension
  622.     Set dsoDimension = m_dsoDatabase.Dimensions.AddNew("Time from 1 column")
  623.  
  624.     ' set the dimension's datasource
  625.     Set dsoDimension.DataSource = m_dsoDatabase.DataSources("Foodmart Sample Database")
  626.     
  627.     ' get the quoting characters from the datasource
  628.     Dim sLQuote As String, sRQuote As String
  629.     sLQuote = dsoDimension.DataSource.OpenQuoteChar
  630.     sRQuote = dsoDimension.DataSource.CloseQuoteChar
  631.     
  632.     ' set the dimension type to time dimension
  633.     ' NOTE: this is important as it enables the OLAP server to
  634.     '       apply time functions to members of this dimension
  635.     dsoDimension.DimensionType = dimTime
  636.     
  637.     ' set the comma separated list of the dimension tables
  638.     ' NOTE: the tables must be quoted
  639.     ' the Time dimension uses only the "time_by_day" table
  640.     dsoDimension.FromClause = sLQuote & "time_by_day" & sRQuote
  641.                               
  642.     ' define the joins between tables used by this dimension
  643.     ' the format of this property is
  644.     '   (table1.columnX = table2.columnY) and (table2.columnZ = table3.columnW)
  645.     ' since the Time dimension is based on only one table, we have no joins
  646.     dsoDimension.JoinClause = ""
  647.     
  648.     
  649.     '
  650.     ' create dimension levels
  651.     '
  652.     Dim dsoLevel As DSO.Level
  653.     
  654.     '
  655.     ' create the All level
  656.     '   the All level is the top-most level in the dimension hierarcy
  657.     On Error GoTo Err_Create
  658.     Set dsoLevel = dsoDimension.Levels.AddNew("All")
  659.     
  660.     ' set the level type
  661.     dsoLevel.LevelType = levAll
  662.     
  663.     ' the All level has only one member
  664.     ' set the MemberKeyColumn of the All level to a constant
  665.     ' this constant is at the same time the name of that single member
  666.     dsoLevel.MemberKeyColumn = "All Years"
  667.     
  668.     '
  669.     ' create the Year level
  670.     '   the Year level contains all of the years
  671.     On Error GoTo Err_Create
  672.     Set dsoLevel = dsoDimension.Levels.AddNew("Year")
  673.     
  674.     ' set the level type
  675.     dsoLevel.LevelType = levTimeYears
  676.     
  677.     ' define which column contains the level member keys
  678.     ' NOTE: we are using DatePart function to extract the year
  679.     '       from the DateTime column ("the_date")
  680.     dsoLevel.MemberKeyColumn = "DatePart('yyyy'," & _
  681.                                 sLQuote & "time_by_day" & sRQuote & "." & _
  682.                                 sLQuote & "the_date" & sRQuote & _
  683.                                 ")"
  684.  
  685.     ' tell DSO how many members this level has
  686.     ' there are 2 years in the "time_by_day" table: 1997 and 1998
  687.     dsoLevel.EstimatedSize = 2
  688.     
  689.     ' this level contains unique members
  690.     dsoLevel.IsUnique = True
  691.     
  692.     ' DSO needs to know what is the data and maximum size of the members keys
  693.     ' NOTE: the ColumnSize property needs to be set only for
  694.     '       levels that have string members
  695.     dsoLevel.ColumnType = adSmallInt
  696.     
  697.     ' specify how should the level members be ordered
  698.     ' we want the countries ordered by Name
  699.     dsoLevel.Ordering = orderName
  700.     
  701.     '
  702.     ' create the Quarter level
  703.     '   the Quarter level contains all of the quarters
  704.     On Error GoTo Err_Create
  705.     Set dsoLevel = dsoDimension.Levels.AddNew("Quarter")
  706.     
  707.     ' set the level type
  708.     dsoLevel.LevelType = levTimeQuarters
  709.     
  710.     ' "quarter" column contains members for this level
  711.     ' NOTE: we are using DatePart function to extract the quarter
  712.     '       from the DateTime column ("the_date")
  713.     dsoLevel.MemberKeyColumn = "DatePart('q'," & _
  714.                                 sLQuote & "time_by_day" & sRQuote & "." & _
  715.                                 sLQuote & "the_date" & sRQuote & _
  716.                                 ")"
  717.  
  718.     ' lets give the quarter members nice names by setting the
  719.     ' MemberNameColumn property of this level
  720.     ' NOTE: if we do not set the MemberNameColumn, member keys will
  721.     '       be used also as member names
  722.     dsoLevel.MemberNameColumn = "'Quarter ' + Format(" & _
  723.                                     "DatePart('q'," & _
  724.                                     sLQuote & "time_by_day" & sRQuote & "." & _
  725.                                     sLQuote & "the_date" & sRQuote & _
  726.                                     ")" & _
  727.                                 ")"
  728.     
  729.     ' there are 8 distinct quarters in the "time_by_day" table
  730.     ' 4 belong to 1997, and 4 belong to 1998
  731.     dsoLevel.EstimatedSize = 8
  732.     
  733.     ' this level DOES NOT contains unique members
  734.     ' ex. Quarter 1 appears both in year 1997 and 1998
  735.     dsoLevel.IsUnique = False
  736.     
  737.     ' DSO needs to know what is the type and maximum size of the members keys
  738.     dsoLevel.ColumnType = adChar
  739.     dsoLevel.ColumnSize = 2             ' quarters are represented as Q1, Q2, ...
  740.                                         ' they can fit in 2 characters
  741.     
  742.     ' we want the quarters ordered by Name
  743.     dsoLevel.Ordering = orderName
  744.     
  745.     '
  746.     ' create the Month level
  747.     '   the Month level contains all of the months
  748.     On Error GoTo Err_Create
  749.     Set dsoLevel = dsoDimension.Levels.AddNew("Month")
  750.     
  751.     ' set the level type
  752.     dsoLevel.LevelType = levTimeMonths
  753.     
  754.     ' "month_of_year" column contains members for this level
  755.     dsoLevel.MemberKeyColumn = "DatePart('m'," & _
  756.                                 sLQuote & "time_by_day" & sRQuote & "." & _
  757.                                 sLQuote & "the_date" & sRQuote & _
  758.                                 ")"
  759.  
  760.     ' get the month names (January, February, ...)
  761.     ' we can use the Format$ function to get the full month name
  762.     dsoLevel.MemberNameColumn = "Format(" & _
  763.                                     sLQuote & "time_by_day" & sRQuote & "." & _
  764.                                     sLQuote & "the_date" & sRQuote & _
  765.                                 ", 'mmmm')"
  766.     
  767.     ' there are 24 distinct months in the "time_by_day" table
  768.     ' 12 belong to 1997, and 12 belong to 1998
  769.     dsoLevel.EstimatedSize = 24
  770.     
  771.     ' this level DOES NOT contain unique members,
  772.     ' ex. January appears both in 1997 and 1998
  773.     dsoLevel.IsUnique = False
  774.     
  775.     ' DSO needs to know what is the type and maximum size of the members keys
  776.     dsoLevel.ColumnType = adSmallInt
  777.     
  778.     ' we want the months ordered by Key (1, 2, 3, ...)
  779.     ' rather than by name (April, August, ...)
  780.     dsoLevel.Ordering = orderKey
  781.     
  782.     
  783.     ' save the dimension definition in the metadata repository
  784.     On Error GoTo Err_Update
  785.     dsoDimension.Update
  786.     
  787. Exit Sub
  788.  
  789. Err_Create:
  790.     ' Failed to create the object.
  791.     ' Possible reasons:
  792.     '   - the DSO database object is being locked by another DSO application
  793.     '       a DSO object is locked while AddNew method is executing on
  794.     '       one of its collections (Datasources, MDStores, Dimensions...)
  795.     '   - the metadata repository is unreachable
  796.  
  797. Err_Update:
  798.     ' Failed to persist the dimension definition in the metadata repository
  799.     ' Possible reasons:
  800.     '   - the metadata repository is unreachable
  801.     '       you can see where the metadata repository resides by looking
  802.     '       up the following registry entry:
  803.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  804.     '           Repository Connection String
  805.     '   - the DSO dimension object is being locked by another DSO application
  806.     '       it is not possible for two DSO apps to persist the same object
  807.     '       at the same time
  808.     '       it is not possible to persist a DSO object, it another DSO app
  809.     '       has explicitly locked it
  810.  
  811.     MsgBox "Create dimension Time failed" & vbCrLf & Err.Description
  812. End Sub
  813.  
  814.  
  815. '
  816. '   CreateDimensionProduct - create the Product dimension
  817. '
  818. '   NOTE: the Product dimension is an example of a snowflake dimension
  819. '         (dimension based on multiple tables)
  820. '
  821. Public Sub CreateDimensionProduct()
  822.     ' create the Product dimension in the database's
  823.     ' Dimensions collection
  824.     On Error GoTo Err_Create
  825.     Dim dsoDimension As DSO.Dimension
  826.     Set dsoDimension = m_dsoDatabase.Dimensions.AddNew("Product")
  827.  
  828.     ' set the dimension description
  829.     dsoDimension.Description = "The Product hierarchy"
  830.     
  831.     ' set the dimension's datasource
  832.     Set dsoDimension.DataSource = m_dsoDatabase.DataSources("Foodmart Sample Database")
  833.     
  834.     ' get the quoting characters from the datasource
  835.     Dim sLQuote As String, sRQuote As String
  836.     sLQuote = dsoDimension.DataSource.OpenQuoteChar
  837.     sRQuote = dsoDimension.DataSource.CloseQuoteChar
  838.     
  839.     ' set the dimension type
  840.     dsoDimension.DimensionType = dimRegular
  841.     
  842.     ' set the comma separated list of the dimension tables
  843.     ' NOTE: the tables must be quoted
  844.     ' the Product dimension uses "product" and "product_class" tables
  845.     dsoDimension.FromClause = sLQuote & "product" & sRQuote & _
  846.                               ", " & _
  847.                               sLQuote & "product_class" & sRQuote
  848.                                   
  849.     ' define the joins between tables used by this dimension
  850.     ' the two product tables are joined by "product_class_id" column
  851.     dsoDimension.JoinClause = "(" & sLQuote & "product" & sRQuote & "." & _
  852.                               sLQuote & "product_class_id" & sRQuote & _
  853.                               " = " & _
  854.                               sLQuote & "product_class" & sRQuote & "." & _
  855.                               sLQuote & "product_class_id" & sRQuote & ")"
  856.  
  857.     '
  858.     ' create dimension levels
  859.     '
  860.     Dim dsoLevel As DSO.Level
  861.     
  862.     '
  863.     ' create the All level
  864.     '   the All level is the top-most level in the dimension hierarcy
  865.     On Error GoTo Err_Create
  866.     Set dsoLevel = dsoDimension.Levels.AddNew("All")
  867.     
  868.     ' set the level type
  869.     dsoLevel.LevelType = levAll
  870.     
  871.     ' the All level has only one member
  872.     ' set the MemberKeyColumn of the All level to a constant
  873.     ' this constant is at the same Product the name of that single member
  874.     dsoLevel.MemberKeyColumn = "All Products"
  875.     
  876.     
  877.     '
  878.     ' create the Product Family level
  879.     '   this level contains aggregates all products
  880.     On Error GoTo Err_Create
  881.     Set dsoLevel = dsoDimension.Levels.AddNew("Product Family")
  882.     
  883.     ' set the level type
  884.     dsoLevel.LevelType = levRegular
  885.     
  886.     ' define which column contains the level member keys
  887.     ' sLQuote and sRQuote are obtained from dsoDimension.Datasource
  888.     ' NOTE: the tables and columns must be quoted using the quoting
  889.     '       characters obtained from the dimension's datasource
  890.     dsoLevel.MemberKeyColumn = sLQuote & "product_class" & sRQuote & "." & _
  891.                                sLQuote & "product_family" & sRQuote
  892.  
  893.     ' tell DSO how many members this level has
  894.     ' this information will be used during the design of aggregations
  895.     '   when determining the optimal set of aggregations
  896.     ' there are 3 product families in the
  897.     '   "product_class" table: Drink, Food, and Non_Consumable
  898.     dsoLevel.EstimatedSize = 3
  899.     
  900.     ' this level contains unique members
  901.     dsoLevel.IsUnique = True
  902.     
  903.     ' DSO needs to know what is the type and maximum size of the level members  keys
  904.     ' NOTE: the ColumnSize property needs to be set only for
  905.     '       levels that have string members
  906.     dsoLevel.ColumnType = adChar
  907.     dsoLevel.ColumnSize = 14            ' the longest member ("Non_Consumable")
  908.                                         ' they can fit in 14 characters
  909.     
  910.     ' specify how should the level members be ordered
  911.     ' we want the members ordered by Name
  912.     dsoLevel.Ordering = orderName
  913.     
  914.     
  915.     '
  916.     ' create the Product Category level
  917.     '   this level contains all of the product categories
  918.     On Error GoTo Err_Create
  919.     Set dsoLevel = dsoDimension.Levels.AddNew("Product Category")
  920.     
  921.     ' set the level type
  922.     dsoLevel.LevelType = levRegular
  923.     
  924.     ' "product_category" column contains members for this level
  925.     dsoLevel.MemberKeyColumn = sLQuote & "product_class" & sRQuote & "." & _
  926.                                sLQuote & "product_category" & sRQuote
  927.  
  928.     ' there are 47 distinct categories in the "time_by_day" table
  929.     '   (note that 'Dairy' shows up under both Food and Drinks product families)
  930.     ' NOTE: you can use the following query to find out
  931.     '       the number of distinct members
  932.     '           SELECT DISTINCT product_class.product_family,
  933.     '                           product_class.product_category
  934.     '           FROM product_class, product
  935.     '           WHERE product_class.product_class_id = product.product_class_id
  936.     '
  937.     dsoLevel.EstimatedSize = 47
  938.     
  939.     ' this level DOES NOT contains unique members because
  940.     ' 'Dairy' shows up under both Food and Drinks product families
  941.     dsoLevel.IsUnique = False
  942.     
  943.     ' DSO needs to know what is the type and maximum size of the members keys
  944.     dsoLevel.ColumnType = adChar
  945.     dsoLevel.ColumnSize = 50            ' 50 characters should do it
  946.     
  947.     ' we want the categories ordered by Name
  948.     dsoLevel.Ordering = orderName
  949.     
  950.     
  951.     '
  952.     ' create the Brand Name level
  953.     '   this level contains all of the brand names
  954.     On Error GoTo Err_Create
  955.     Set dsoLevel = dsoDimension.Levels.AddNew("Brand Name")
  956.     
  957.     ' set the level type
  958.     dsoLevel.LevelType = levRegular
  959.     
  960.     ' "brand_name" column contains members for this level
  961.     dsoLevel.MemberKeyColumn = sLQuote & "product" & sRQuote & "." & _
  962.                                sLQuote & "brand_name" & sRQuote
  963.     
  964.     ' there are 276 distinct brands
  965.     ' NOTE: you can use the following query to
  966.     '       count the distinct members for this level
  967.     '       SELECT DISTINCT product_class.product_family,
  968.     '                       product_class.product_category,
  969.     '                       product.brand_name
  970.     '       FROM product_class, product
  971.     '       WHERE product_class.product_class_id = product.product_class_id
  972.     '
  973.     dsoLevel.EstimatedSize = 276
  974.     
  975.     ' this level DOES NOT contain unique members, because
  976.     ' BBB Best appears both under the Hot Beverages and Baking Goods categories
  977.     dsoLevel.IsUnique = False
  978.     
  979.     ' DSO needs to know what is the type and maximum size of the members keys
  980.     dsoLevel.ColumnType = adChar
  981.     dsoLevel.ColumnSize = 20            ' no brand name is longer
  982.                                         ' than 20 characters
  983.     
  984.     ' we want the brands ordered by name
  985.     dsoLevel.Ordering = orderName
  986.     
  987.     
  988.     '
  989.     ' create the Product Name level
  990.     '   this level contains all of the brand names
  991.     On Error GoTo Err_Create
  992.     Set dsoLevel = dsoDimension.Levels.AddNew("Product Name")
  993.     
  994.     ' set the level type
  995.     dsoLevel.LevelType = levRegular
  996.     
  997.     ' "product_id" column contains member keys for this level
  998.     dsoLevel.MemberKeyColumn = sLQuote & "product" & sRQuote & "." & _
  999.                                sLQuote & "product_id" & sRQuote
  1000.     
  1001.     ' we will use the "product_name" column for member names
  1002.     dsoLevel.MemberNameColumn = sLQuote & "product" & sRQuote & "." & _
  1003.                                 sLQuote & "product_name" & sRQuote
  1004.     
  1005.     ' there are 1560 distinct products
  1006.     ' NOTE: you can use the following query to
  1007.     '       count the distinct members for this level
  1008.     '       SELECT DISTINCT product_class.product_family,
  1009.     '                       product_class.product_category,
  1010.     '                       product.brand_name,
  1011.     '                       product_id
  1012.     '       FROM product_class, product
  1013.     '       WHERE product_class.product_class_id = product.product_class_id
  1014.     '
  1015.     dsoLevel.EstimatedSize = 1560
  1016.     
  1017.     ' this level contains unique members
  1018.     dsoLevel.IsUnique = True
  1019.     
  1020.     ' DSO needs to know what is the type of the members keys
  1021.     dsoLevel.ColumnType = adInteger
  1022.     
  1023.     ' we want the brands ordered by name
  1024.     dsoLevel.Ordering = orderName
  1025.     
  1026.     ' create the Low Fat member property for this level
  1027.     Dim dsoMemberProperty As DSO.MemberProperty
  1028.     Set dsoMemberProperty = dsoLevel.MemberProperties.AddNew("Low Fat")
  1029.     dsoMemberProperty.SourceColumn = sLQuote & "product" & sRQuote & "." & _
  1030.                                      sLQuote & "low_fat" & sRQuote
  1031.                                      
  1032.     ' save the dimension definition in the metadata repository
  1033.     On Error GoTo Err_Update
  1034.     dsoDimension.Update
  1035.     
  1036. Exit Sub
  1037.  
  1038. Err_Create:
  1039.     ' Failed to create the object.
  1040.     ' Possible reasons:
  1041.     '   - the DSO database object is being locked by another DSO application
  1042.     '       a DSO object is locked while AddNew method is executing on
  1043.     '       one of its collections (Datasources, MDStores, Dimensions...)
  1044.     '   - the metadata repository is unreachable
  1045.  
  1046. Err_Update:
  1047.     ' Failed to persist the dimension definition in the metadata repository
  1048.     ' Possible reasons:
  1049.     '   - the metadata repository is unreachable
  1050.     '       you can see where the metadata repository resides by looking
  1051.     '       up the following registry entry:
  1052.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  1053.     '           Repository Connection String
  1054.     '   - the DSO dimension object is being locked by another DSO application
  1055.     '       it is not possible for two DSO apps to persist the same object
  1056.     '       at the same time
  1057.     '       it is not possible to persist a DSO object, it another DSO app
  1058.     '       has explicitly locked it
  1059.  
  1060.     MsgBox "Create dimension Product failed" & vbCrLf & Err.Description
  1061. End Sub
  1062.  
  1063.  
  1064. '
  1065. '   CreateRole -    create a role in the database
  1066. '                   Role is a group of users with the same
  1067. '                   access privileges
  1068. Public Sub CreateRole()
  1069.     ' create the role in the database's
  1070.     ' Roles collection
  1071.     On Error GoTo Err_Create
  1072.     Dim dsoRole As DSO.Role
  1073.     Set dsoRole = m_dsoDatabase.Roles.AddNew("Everyone")
  1074.     
  1075.     ' set the semi-colon separated list of users who belong to this role
  1076.     ' make sure that the users are valid NT users, otherwise DSO will
  1077.     ' raise an error
  1078.     ' format: <domain name>\<user name>[;<domain name>\<user name>...]
  1079.     dsoRole.UsersList = "Everyone"
  1080.     
  1081.     ' save the role definition in the metadata repository
  1082.     On Error GoTo Err_Update
  1083.     dsoRole.Update
  1084.     
  1085. Exit Sub
  1086.  
  1087. Err_Create:
  1088.     ' Failed to create the object.
  1089.     ' Possible reasons:
  1090.     '   - the DSO database object is being locked by another DSO application
  1091.     '       a DSO object is locked while AddNew method is executing on
  1092.     '       one of its collections (Datasources, MDStores, Dimensions...)
  1093.     '   - the metadata repository is unreachable
  1094.  
  1095. Err_Update:
  1096.     ' Failed to persist the role definition in the metadata repository
  1097.     ' Possible reasons:
  1098.     '   - the metadata repository is unreachable
  1099.     '       you can see where the metadata repository resides by looking
  1100.     '       up the following registry entry:
  1101.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  1102.     '           Repository Connection String
  1103.     '   - the DSO role object is being locked by another DSO application
  1104.     '       it is not possible for two DSO apps to persist the same object
  1105.     '       at the same time
  1106.     '       it is not possible to persist a DSO object, it another DSO app
  1107.     '       has explicitly locked it
  1108.  
  1109.     MsgBox "Create role Everyone failed" & vbCrLf & Err.Description
  1110. End Sub
  1111.  
  1112.  
  1113. '
  1114. '   CreateCube - create the Sales cube
  1115. '
  1116. '
  1117. Public Sub CreateCube()
  1118.     ' create the Sales cube in the database's
  1119.     ' MDStores collection
  1120.     On Error GoTo Err_Create
  1121.     Dim dsoCube As DSO.MDStore
  1122.     Set dsoCube = m_dsoDatabase.MDStores.AddNew("Sales")
  1123.  
  1124.     ' set the cube's description
  1125.     dsoCube.Description = "The Sales cube"
  1126.     
  1127.     ' set the cube's datasource
  1128.     ' use the datasource that was created in the database's Datasources collection
  1129.     dsoCube.DataSources.Add m_dsoDatabase.DataSources("Foodmart Sample Database")
  1130.     
  1131.     ' get the quoting characters from the datasource
  1132.     Dim sLQuote As String, sRQuote As String
  1133.     sLQuote = dsoCube.DataSources(1).OpenQuoteChar
  1134.     sRQuote = dsoCube.DataSources(1).CloseQuoteChar
  1135.  
  1136.     ' set the source table (fact table) for the cube
  1137.     dsoCube.SourceTable = sLQuote & "sales_fact_1998" & sRQuote
  1138.     
  1139.     ' set the number of rows from the fact table that will be included in the cube
  1140.     ' since we want the whole table (we did not specify anything for SourceTableFilter)
  1141.     '   we can obtain this number by doing SELECT COUNT(*) FROM sales_fact_1998
  1142.     dsoCube.EstimatedRows = 164558
  1143.     
  1144.     ' specify access permissions to the cube by adding roles to the cube
  1145.     ' we will add the role that we have created in the database
  1146.     ' and allow users in that role to have both read and write access to the cube
  1147.     Dim dsoCubeRole As DSO.Role
  1148.     Set dsoCubeRole = dsoCube.Roles.AddNew("Everyone")
  1149.     dsoCubeRole.SetPermissions "Access", "RW"
  1150.     
  1151.     '
  1152.     ' create cube's measures
  1153.     '
  1154.     Dim dsoMeasure As DSO.Measure
  1155.     
  1156.     ' create a measure for Store Sales
  1157.     Set dsoMeasure = dsoCube.Measures.AddNew("Store Sales")
  1158.     
  1159.     ' set the measure's source column, data type and the formatting
  1160.     dsoMeasure.SourceColumn = dsoCube.SourceTable & "." & _
  1161.                               sLQuote & "store_sales" & sRQuote
  1162.     dsoMeasure.SourceColumnType = adDouble
  1163.     dsoMeasure.FormatString = "Currency"
  1164.     
  1165.     ' this measure will be aggregated by summation
  1166.     dsoMeasure.AggregateFunction = aggSum
  1167.     
  1168.     
  1169.     ' create a measure for Store Cost
  1170.     Set dsoMeasure = dsoCube.Measures.AddNew("Store Cost")
  1171.     
  1172.     ' set the measure's source column, data type and the formatting
  1173.     dsoMeasure.SourceColumn = dsoCube.SourceTable & "." & _
  1174.                               sLQuote & "store_cost" & sRQuote
  1175.     dsoMeasure.SourceColumnType = adDouble
  1176.     dsoMeasure.FormatString = "Currency"
  1177.     
  1178.     ' this measure will be aggregated by summation
  1179.     dsoMeasure.AggregateFunction = aggSum
  1180.     
  1181.     ' create a measure for Sales Count
  1182.     ' Sales Count will be the number of all products sold
  1183.     Set dsoMeasure = dsoCube.Measures.AddNew("Sales Count")
  1184.     
  1185.     ' set the measure's source column, data type and the formatting
  1186.     dsoMeasure.SourceColumn = dsoCube.SourceTable & "." & _
  1187.                               sLQuote & "product_id" & sRQuote
  1188.     dsoMeasure.SourceColumnType = adInteger
  1189.     dsoMeasure.FormatString = "Standard"
  1190.     
  1191.     ' this measure will be aggregated by counting
  1192.     dsoMeasure.AggregateFunction = aggCount
  1193.     
  1194.     
  1195.     ' create a measure for Store Profit
  1196.     ' Profit = Sales - Cost
  1197.     Set dsoMeasure = dsoCube.Measures.AddNew("Store Profit")
  1198.     
  1199.     ' set the measure's source column, data type and the formatting
  1200.     dsoMeasure.SourceColumn = dsoCube.SourceTable & "." & _
  1201.                               sLQuote & "store_sales" & sRQuote & _
  1202.                               " - " & _
  1203.                               dsoCube.SourceTable & "." & _
  1204.                               sLQuote & "store_cost" & sRQuote
  1205.                               
  1206.     dsoMeasure.SourceColumnType = adDouble
  1207.     dsoMeasure.FormatString = "Currency"
  1208.     
  1209.     ' this measure will be aggregated by summation
  1210.     dsoMeasure.AggregateFunction = aggSum
  1211.     
  1212.     
  1213.     '
  1214.     '   add dimensions to the cube
  1215.     '
  1216.     
  1217.     ' add the Product dimension
  1218.     ' note that by adding the dimension to the cube
  1219.     '   all of the dimension levels are automatically inherited from
  1220.     '   the corresponding database dimension
  1221.     ' Note: If you do not intend to refer to the newly added cube
  1222.     '       dimension, you don't need to declare a variable and instead call
  1223.     '           dsoCube.Dimensions.AddNew <dimensionname>
  1224.     '       as a Sub.
  1225.     Dim dsoProductCubeDim As DSO.Dimension
  1226.     Set dsoProductCubeDim = dsoCube.Dimensions.AddNew("Product")
  1227.     
  1228.     ' add the Time dimension
  1229.     Dim dsoTimeCubeDim As DSO.Dimension
  1230.     Set dsoTimeCubeDim = dsoCube.Dimensions.AddNew("Time")
  1231.     
  1232.     ' add the Store dimension
  1233.     Dim dsoStoreCubeDim As DSO.Dimension
  1234.     Set dsoStoreCubeDim = dsoCube.Dimensions.AddNew("Store")
  1235.     
  1236.     ' get the list of all tables used in this cube
  1237.     ' this list includes the fact table and the dimension tables
  1238.     ' Note: Make sure that you do not repeat the same table name twice.
  1239.     dsoCube.FromClause = dsoCube.SourceTable & ", " & _
  1240.                          dsoStoreCubeDim.FromClause & ", " & _
  1241.                          dsoTimeCubeDim.FromClause & ", " & _
  1242.                          dsoProductCubeDim.FromClause
  1243.  
  1244.     ' define the joins between tables used by the cube
  1245.     
  1246.     ' first define the join between the fact table and the Store table
  1247.     dsoCube.JoinClause = _
  1248.             "(" & _
  1249.                 sLQuote & "sales_fact_1998" & sRQuote & "." & sLQuote & "store_id" & sRQuote & _
  1250.                 " = " & _
  1251.                 sLQuote & "store" & sRQuote & "." & sLQuote & "store_id" & sRQuote & _
  1252.             ")"
  1253.     
  1254.     ' define the join between the fact table and the Time table
  1255.     dsoCube.JoinClause = dsoCube.JoinClause & " AND " & _
  1256.             "(" & _
  1257.                sLQuote & "sales_fact_1998" & sRQuote & "." & sLQuote & "time_id" & sRQuote & _
  1258.                " = " & _
  1259.                sLQuote & "time_by_day" & sRQuote & "." & sLQuote & "time_id" & sRQuote & _
  1260.             ")"
  1261.     
  1262.     ' define the join between the fact table and the Product table
  1263.     dsoCube.JoinClause = dsoCube.JoinClause & " AND " & _
  1264.             "(" & _
  1265.                sLQuote & "sales_fact_1998" & sRQuote & "." & sLQuote & "product_id" & sRQuote & _
  1266.                " = " & _
  1267.                sLQuote & "product" & sRQuote & "." & sLQuote & "product_id" & sRQuote & _
  1268.             ")"
  1269.     
  1270.     ' finally define the join between the Product table and the Product_class table
  1271.     dsoCube.JoinClause = dsoCube.JoinClause & " AND " & _
  1272.             "(" & _
  1273.                sLQuote & "product" & sRQuote & "." & sLQuote & "product_class_id" & sRQuote & _
  1274.                " = " & _
  1275.                sLQuote & "product_class" & sRQuote & "." & sLQuote & "product_class_id" & sRQuote & _
  1276.             ")"
  1277.     
  1278.     ' save the cube definition in the metadata repository
  1279.     On Error GoTo Err_Update
  1280.     dsoCube.Update
  1281.     
  1282.     ' store the reference to the cube object
  1283.     ' so that other methods can use it
  1284.     Set m_dsoCube = dsoCube
  1285.  
  1286. Exit Sub
  1287.  
  1288. Err_Create:
  1289.     ' Failed to create the object.
  1290.     ' Possible reasons:
  1291.     '   - the DSO database object is being locked by another DSO application
  1292.     '       a DSO object is locked while AddNew method is executing on
  1293.     '       one of its collections (Datasources, MDStores, Dimensions...)
  1294.     '   - the metadata repository is unreachable
  1295.  
  1296. Err_Update:
  1297.     ' Failed to persist the cube definition in the metadata repository
  1298.     ' Possible reasons:
  1299.     '   - the metadata repository is unreachable
  1300.     '       you can see where the metadata repository resides by looking
  1301.     '       up the following registry entry:
  1302.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  1303.     '           Repository Connection String
  1304.     '   - the DSO cube object is being locked by another DSO application
  1305.     '       it is not possible for two DSO apps to persist the same object
  1306.     '       at the same time
  1307.     '       it is not possible to persist a DSO object, it another DSO app
  1308.     '       has explicitly locked it
  1309.  
  1310.     MsgBox "Create cube Sales failed" & vbCrLf & Err.Description
  1311. End Sub
  1312.  
  1313.  
  1314. '
  1315. '   CreateAggregations - design aggregations for the cube
  1316. '
  1317. Public Sub CreateAggregations()
  1318.     ' aggregations are designed per partition
  1319.     ' get the default partition from the cube
  1320.     Dim dsoPartition As DSO.MDStore
  1321.     Set dsoPartition = m_dsoCube.MDStores(1)
  1322.     
  1323.     ' first we need to set the storage mode of the partition
  1324.     ' we will set it to MOLAP
  1325.     ' (facts and aggregations are loaded into multidimensional structures on
  1326.     '   the OLAP server)
  1327.     dsoPartition.OlapMode = olapmodeMolapIndex
  1328.     
  1329.     ' get the partition analyzer
  1330.     Dim dsoPartitionAnalyzer As DSO.PartitionAnalyzer
  1331.     Set dsoPartitionAnalyzer = dsoPartition.Analyzer
  1332.     
  1333.     ' initialize the analyzer
  1334.     dsoPartitionAnalyzer.InitializeDesign
  1335.     
  1336.     ' we will design aggregations for 20% of queries
  1337.     ' NextAnalysisStep incrementaly builds the optimal set of aggregations
  1338.     ' we will stop when PercentageBenefit reaches 20
  1339.     Dim PercentageBenefit As Double
  1340.     Dim AccumulatedSize As Double
  1341.     Dim AggregationsCount As Long
  1342.     Do While dsoPartitionAnalyzer.NextAnalysisStep(PercentageBenefit, _
  1343.                                                    AccumulatedSize, _
  1344.                                                    AggregationsCount)
  1345.         If PercentageBenefit > 20# Then
  1346.             ' Reached 20% optimization.
  1347.             Exit Do
  1348.         End If
  1349.     Loop
  1350.     
  1351.     ' apply the designed aggregations to the partition
  1352.     Dim dsoAggregation As DSO.MDStore
  1353.     For Each dsoAggregation In dsoPartitionAnalyzer.DesignedAggregations
  1354.         dsoPartition.MDStores.Add dsoAggregation
  1355.     Next
  1356.     
  1357.     ' close the analyzer
  1358.     dsoPartitionAnalyzer.CloseAggregationsAnalysis
  1359.     
  1360.     ' save the partition definition in the metadata repository
  1361.     On Error GoTo Err_Update
  1362.     dsoPartition.Update
  1363.  
  1364. Exit Sub
  1365.  
  1366. Err_Update:
  1367.     ' Failed to persist the cube definition in the metadata repository
  1368.     ' Possible reasons:
  1369.     '   - the metadata repository is unreachable
  1370.     '       you can see where the metadata repository resides by looking
  1371.     '       up the following registry entry:
  1372.     '       HKEY_LOCAL_MACHINE\Software\Microsoft\OLAP Server\Server Connection Info
  1373.     '           Repository Connection String
  1374.     '   - the DSO cube object is being locked by another DSO application
  1375.     '       it is not possible for two DSO apps to persist the same object
  1376.     '       at the same time
  1377.     '       it is not possible to persist a DSO object, it another DSO app
  1378.     '       has explicitly locked it
  1379.  
  1380.     MsgBox "Design aggregations for Partition failed" & vbCrLf & Err.Description
  1381. End Sub
  1382.  
  1383.  
  1384. '
  1385. '   ProcessDatabase - processes the whole DSO database
  1386. '
  1387. Public Sub ProcessDatabase()
  1388.     On Error GoTo Err_Process
  1389.     
  1390.     ' Note, although processing the whole database could
  1391.     '       have been done with a single call:
  1392.     '           m_dsoDatabase.Process
  1393.     '       The function outlines the individual calls that are made
  1394.     '       to process dimensions and cubes within a single transaction
  1395.     
  1396.     ' Begin transaction
  1397.     m_dsoDatabase.BeginTrans
  1398.     
  1399.     ' Process all of the dimensions
  1400.     Dim dsoDim As DSO.Dimension
  1401.     For Each dsoDim In m_dsoDatabase.Dimensions
  1402.         dsoDim.Process processFull
  1403.     Next
  1404.     
  1405.     ' Process the cube (the first and only).
  1406.     Dim dsoCube As DSO.MDStore
  1407.     Set dsoCube = m_dsoDatabase.MDStores(1)
  1408.     dsoCube.Process processFull
  1409.     
  1410.     ' Commit the transaction
  1411.     m_dsoDatabase.CommitTrans
  1412.     
  1413.  
  1414.  
  1415. Exit Sub
  1416.  
  1417. Err_Process:
  1418.     ' Processing of the database failes.
  1419.     ' Possible reasons:
  1420.     '   - OLAP server is not running or unreachable
  1421.     '   - connection to the relational data source cannot be established
  1422.     '   - cube or dimensions are not properly defined
  1423.     '   - another app is processing one of the cubes or dimensions from this
  1424.     '     database
  1425.     '   - another app has locked one of the cubes or dimensions from this
  1426.     '     database
  1427.     
  1428.     ' Rollback the transaction in case of failure.
  1429.     m_dsoDatabase.Rollback
  1430.     
  1431.     MsgBox "Process database failed" & vbCrLf & Err.Description
  1432.  
  1433. End Sub
  1434.